/******************************************************************
*
*	CyberUPnP for Java
*
*	Copyright (C) Satoshi Konno 2002
*
*	File: SSDP.java
*
*	Revision;
*
*	11/18/02
*		- first revision.
*	05/13/03
*		- Added constants for IPv6.
*	08/03/05
*		- Thanks for Stefano Lenzi <kismet-sl at users.sourceforge.net>
*		  and Mikael <mhakman at users.sourceforge.net>
*		- Fixed getLeaseTime() to parse normally when the value includes extra strings such as white space.
*	
******************************************************************/

package org.cybergarage.upnp.ssdp;

import org.cybergarage.util.Debug;

/**
 * 
 * This class defines constant value related to SSDP.<br>
 * All the values defined here are complaint to the UPnP Standard 
 * 
 * @author Satoshi "skonno" Konno
 * @author Stefano "Kismet" Lenzi
 * @author Francesco "sygent" Furfari
 * @version 1.8
 *
 */
public class SSDP
{
	////////////////////////////////////////////////
	//	Constants
	////////////////////////////////////////////////
	
	
	/**
	 * Property key used to modify the default destination port for SSDP multicast messages.<br>
	 * Only value between 1024 and 49151 are accepted. 
	 * 
	 * @since 1.8
	 */
	private final static String SSDP_PORT = "cyberdomo.ssdp.port";

	/**
	 * Property key used to modify the default destination port for SSDP multicast messages.<br>
	 * Only value between 1 and 300 are accepted.
	 * 
	 * @since 1.8
	 */
	private final static String SSDP_MX = "cyberdomo.ssdp.mx";
	
	/**
	 * Property key used to modify the default puffer size for recieving UDP packetes: either HTTP/UDP and HTTP/M-UDP.<br> 
	 * <b>This value is extramly important, do not change unless you know what you are doing.</b>
	 * 
	 * @see {@link DatagramSocket#receive(java.net.DatagramPacket)}},
	 * 		{@link HTTPMUSocket#receive()}, 
	 * 		{@link HTTPUSocket#receive()}
	 * 
	 * @since 1.8
	 */
	private final static String SSDP_BUFFER_SIZE = "cyberdomo.ssdp.buffersize";

	/**
	 * Default destination port for SSDP multicast messages
	 * @see {@link #SSDP_PORT}
	 */
	public static int PORT = 1900;
	
	/**
	 * Default M-SEARCH MX value for SSDP multicast messages
	 * @see {@link #SSDP_MX}
	 */
	public static int DEFAULT_MSEARCH_MX = 5;

	/**
	 * Default buffer size for UDP packet
	 * @see {@link #SSDP_BUFFER_SIZE}
	 */
	public static int RECV_MESSAGE_BUFSIZE = 2048;
	
	/**
	 * Default IPv4 multicast address for SSDP messages
	 */
	public static final String ADDRESS = "239.255.255.250";

	public static final String IPV6_LINK_LOCAL_ADDRESS = "FF02::C";
	public static final String IPV6_SUBNET_ADDRESS = "FF03::C";
	public static final String IPV6_ADMINISTRATIVE_ADDRESS = "FF04::C";
	public static final String IPV6_SITE_LOCAL_ADDRESS = "FF05::C";
	public static final String IPV6_GLOBAL_ADDRESS = "FF0E::C";
	
	private static String IPV6_ADDRESS;

	public static final void setIPv6Address(String addr)
	{
		IPV6_ADDRESS = addr;
	}

	public static final String getIPv6Address()
	{
		return IPV6_ADDRESS;
	}
	

	////////////////////////////////////////////////
	//	Initialize
	////////////////////////////////////////////////

	static {
		setIPv6Address(IPV6_LINK_LOCAL_ADDRESS);

		PORT = 1900;
		String portProperty = System.getProperty(SSDP_PORT);
		if (portProperty != null) {
			try {
				int port = Integer.parseInt(portProperty);
				if (port > 1023 && port < 49151)
					PORT = port;
			} catch (Exception ignored) {
			}
		}
		
		DEFAULT_MSEARCH_MX = 5;
		String mxProperty = System.getProperty(SSDP_MX);
		if (mxProperty != null) {
			try {
				int mx = Integer.parseInt(mxProperty);
				if (mx > 0 && mx < 300)
					DEFAULT_MSEARCH_MX = mx;
			} catch (Exception ignored) {
			}
		}
		
		RECV_MESSAGE_BUFSIZE = 2048;
		String bufSizeProperty = System.getProperty(SSDP_BUFFER_SIZE);
		if (bufSizeProperty != null) {
			try {
				int bufferSize = Integer.parseInt(bufSizeProperty);
				if (bufferSize > 512 && bufferSize < 65536)
					RECV_MESSAGE_BUFSIZE = bufferSize;
			} catch (Exception ignored) {
			}
		}
	}
	
	////////////////////////////////////////////////
	//	LeaseTime
	////////////////////////////////////////////////

	public final static int getLeaseTime(String cacheCont){
		/*
		 * Search for max-age keyword instead of equals sign Found value of
		 * max-age ends at next comma or end of string
		 */ 
		int mx = 0;  
		int maxAgeIdx = cacheCont.indexOf("max-age");  
		if (maxAgeIdx >= 0) {  
			int endIdx = cacheCont.indexOf(',',maxAgeIdx);  
			if (endIdx < 0)  
				endIdx = cacheCont.length();  
			try {  
				maxAgeIdx = cacheCont.indexOf("=",maxAgeIdx); 
				String mxStr = cacheCont.substring(maxAgeIdx+1,endIdx).trim();  
				mx = Integer.parseInt(mxStr);  
			} catch (Exception e) {  
				Debug.warning (e);  
			} 
		}  
		return mx; 
	}
	
	public final static void setGlobalMSearchMX(int mx) {
		DEFAULT_MSEARCH_MX = mx;
	}
	
	public final static int getGlobalMSearchMX() {
		return DEFAULT_MSEARCH_MX;
	}
	
}

